﻿/******************************************************************************
 *  作者：       scott
 *  创建时间：   2012/3/3 15:55:51
 *
 *
 ******************************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using EasyMvcBlog.Infrastructure.Repository.DataMap;
using FluentNHibernate.Cfg;
using FluentNHibernate.Cfg.Db;
using NHibernate;
using NHibernate.Cfg;
using NHibernate.Criterion;
using NHibernate.Linq;
using NHibernate.Context;

namespace EasyMvcBlog.Infrastructure.Repository
{
    /// <summary>
    /// 所有数据访问类的基类，提供最基本的增删改查能力
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class RepositoryBase<T> : IRepository<T> where T : class
    {
        private static ISessionFactory sessionFactory = Configuration.BuildSessionFactory();

        /// <summary>
        /// NHibernate配置信息
        /// </summary>
        public static Configuration Configuration
        {
            get
            {
                return Fluently.Configure().Database(MsSqlConfiguration.MsSql2000
                    .ConnectionString(c => c.FromConnectionStringWithKey("dbConn"))
                    //.ConnectionString(s => s
                    //    .Server("111.68.9.42")
                    //    .Database("EasyMvcBlog")
                    //    .Username("a0216215226")
                    //    .Password("scott")
                    //.Server("(local)")
                    //.Database("EasyMvcBlog")
                    //.Username("sa")
                    //.Password("123456")
                    //.TrustedConnection()
                    //)
                                  .ShowSql())
                    .Mappings(m => m
                                       .FluentMappings
                                       .AddFromAssemblyOf<ArticleMap>())
                    .ExposeConfiguration(cfg => cfg.SetProperty(NHibernate.Cfg.Environment.CurrentSessionContextClass,"web"))
                    .BuildConfiguration();
            }
        }

        /// <summary>
        /// 创建新的Session
        /// </summary>
        public static ISession NHibernateSession
        {
            get
            {
                return sessionFactory.OpenSession();
            }
        }


        public ISession GetNhibernateSession()
        {
            return sessionFactory.OpenSession();

        }

        public void Update(T entity)
        {
            using (ISession session = NHibernateSession)
            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    session.Update(entity);
                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }

        public T Add(T entity)
        {
            //为了保证 操作事物和具体操作的session一致，这个是必须的
            using (ISession session = NHibernateSession)
            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    session.Save(entity);
                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }
            }
            return entity;
        }

        public void Delete(T entity)
        {
            using (ISession session = NHibernateSession)
            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    session.Delete(entity);
                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }

        public void DeleteById<T>(int id)
        {
            using (ISession session = NHibernateSession)
            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    T t = session.Get<T>(id);
                    session.Delete(t);
                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }
            }
        }

        public T GetById(int id)
        {
            T entity;
            using (ISession session = NHibernateSession)
            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    entity = session.Get<T>(id);
                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }
            }
            return entity;
        }

        public List<T> GetList(Expression<Func<T, bool>> expression)
        {
            using (ISession session = NHibernateSession)
            {
                return session.Query<T>().Where(expression.Compile()).ToList();
            }
        }

        public List<T> GetAll()
        {
            using (ISession session = NHibernateSession)
            {
                return session.Query<T>().ToList();
            }
        }

        /// <summary>
        /// 分页
        /// </summary>
        /// <param name="pageIndex">当前页</param>
        /// <param name="pageSize">每页显示数量</param>
        /// <param name="property">排序的字段(不需要排序则为null)</param>
        /// <param name="asc">是否正序排列</param>
        /// <param name="criterias">筛选条件</param>
        /// <returns></returns>
        public IList<T> GetPage(int pageIndex, int pageSize, string property, bool asc,
                                IEnumerable<ICriterion> criterias)
        {
            IList<T> list;
            using (ISession session = NHibernateSession)
            using (ITransaction transaction = session.BeginTransaction())
            {
                try
                {
                    ICriteria ca = session.CreateCriteria<T>();
                    if (criterias != null)
                    {
                        foreach (ICriterion criteria in criterias)
                        {
                            ca.Add(criteria);
                        }
                    }

                    list = ca.SetFirstResult((pageIndex - 1) * pageSize)
                        .SetMaxResults(pageSize)
                        .List<T>();
                    transaction.Commit();
                }
                catch (Exception)
                {
                    transaction.Rollback();
                    throw;
                }
            }
            return list;
        }
    }
}